
import wave
import threading
from os import remove, mkdir, listdir
from os.path import exists, splitext, basename, join
from datetime import datetime
from time import sleep
from shutil import rmtree
import pyaudio
from PIL import ImageGrab
from moviepy.editor import *

CHUNK_SIZE = 1024
CHANNELS = 2
FORMAT = pyaudio.paInt16
RATE = 48000
allowRecording = True


def record_audio():
	p = pyaudio.PyAudio()
	stream = p.open(format=FORMAT, channels=CHANNELS,
					rate=RATE, input=True,
					frames_per_buffer=CHUNK_SIZE)
	wf = wave.open(audio_filename, 'wb')
	wf.setnchannels(CHANNELS)
	wf.setsampwidth(p.get_sample_size(FORMAT))
	wf.setframerate(RATE)
	while allowRecording:
		data = stream.read(CHUNK_SIZE)
		wf.writeframes(data)
	wf.close()
	stream.stop_stream()
	stream.close()
	p.terminate()


def record_screen():
	index = 1
	while allowRecording:
		ImageGrab.grab().save(f'{pic_dir}\{index}.jpg',
							  quality=95, subsampling=0)
		sleep(0.04)
		index = index + 1


audio_filename = str(datetime.now())[:19].replace(':', '_') + '.mp3'
pic_dir = 'pics'
if not exists(pic_dir):
	mkdir(pic_dir)
video_filename = audio_filename[:-3] + 'mp4'
t1 = threading.Timer(3, record_audio)
t2 = threading.Timer(3, record_screen)
t1.start()
t2.start()
print('We will start capture in 3s. You can enter [q] to over.')
while (ch := input()) != 'q':
	pass
allowRecording = False
t1.join()
t2.join()

audio = AudioFileClip(audio_filename)
pic_files = [join(pic_dir, fn) for fn in listdir(pic_dir)
			 if fn.endswith('.jpg')]
pic_files.sort(key=lambda fn: int(splitext(basename(fn))[0]))
each_duration = round(audio.duration / len(pic_files), 4)
image_clips = []
for pic in pic_files:
	image_clips.append(ImageClip(pic,
								 duration=each_duration))
video = concatenate_videoclips(image_clips)
video = video.set_audio(audio)
video.write_videofile(video_filename, codec='mpeg4', fps=24)
remove(audio_filename)
rmtree(pic_dir)
